package com.nageoffer.shortlink.admin.common.util;

import cn.hutool.core.util.StrUtil;
import com.nageoffer.shortlink.admin.common.enums.desensitization.DesensitizationDataTypeEnum;

/**
 * @title: DesensitizationUtil
 * @Author Z先森
 * @Date: 2023/7/19 11:15
 * @Version 1.0
 * @description 脱敏工具类
 */
public class DesensitizationUtil {
    public DesensitizationUtil() {
    }

    public static String desensitized(CharSequence str, DesensitizationDataTypeEnum desensitizedType) {
        if (StrUtil.isBlank(str)) {
            return "";
        } else {
            String newStr = String.valueOf(str);
            switch (desensitizedType.ordinal()) {
                case 1:
                    newStr = String.valueOf(userId());
                    break;
                case 2:
                    newStr = chineseName(String.valueOf(str));
                    break;
                case 3:
                    newStr = idCardNum(String.valueOf(str), 1, 2);
                    break;
                case 4:
                    newStr = fixedPhone(String.valueOf(str));
                    break;
                case 5:
                    newStr = mobilePhone(String.valueOf(str));
                    break;
                case 6:
                    newStr = address(String.valueOf(str));
                    break;
                case 7:
                    newStr = email(String.valueOf(str));
                    break;
                case 8:
                    newStr = password(String.valueOf(str));
                    break;
                case 9:
                    newStr = carLicense(String.valueOf(str));
                    break;
                case 10:
                    newStr = bankCard(String.valueOf(str));
            }

            return newStr;
        }
    }

    public static Long userId() {
        return 0L;
    }

    /**
     * 【中文姓名】只显示第一个汉字，其他隐藏为2个星号，比如：李**
     *
     * @param fullName 姓名
     * @return 脱敏后的姓名
     */
    public static String chineseName(String fullName) {
        return StrUtil.isBlank(fullName) ? "" : StrUtil.hide(fullName, 1, fullName.length());
    }

    /**
     * 【身份证号】显示前1位和后2位，其他隐藏。共计18位或者15位，比如：1*****************1
     *
     * @param idCardNum 身份证号
     * @param front     保留：前面的front位数；从1开始
     * @param end       保留：后面的end位数；从1开始
     * @return 脱敏后的身份证号
     */
    public static String idCardNum(String idCardNum, int front, int end) {
        if (StrUtil.isBlank(idCardNum)) {
            return "";
        } else if (front + end > idCardNum.length()) {
            return "";
        } else {
            return front >= 0 && end >= 0 ? StrUtil.hide(idCardNum, front, idCardNum.length() - end) : "";
        }
    }

    /**
     * 【固定电话】 前四位，后两位
     *
     * @param num 固定电话
     * @return 脱敏后的固定电话
     */
    public static String fixedPhone(String num) {
        return StrUtil.isBlank(num) ? "" : StrUtil.hide(num, 4, num.length() - 2);
    }

    /**
     * 【手机号码】前三位，后四位，其他隐藏，比如：138******1234
     *
     * @param num 手机号码
     * @return 脱敏后的手机号码
     */
    public static String mobilePhone(String num) {
        return StrUtil.isBlank(num) ? "" : StrUtil.hide(num, 3, num.length() - 4);
    }

    /**
     * 【地址】只显示到地区的三分之二，尾部脱敏，不显示详细地址，比如：北京市海淀区****
     *
     * @param address 地址
     * @return 脱敏后的地址
     */
    public static String address(String address) {
        if (StrUtil.isBlank(address)) {
            return "";
        } else {
            // 地址尾部脱敏三分之一
            int length = address.length();
            int end = length / 3;
            return StrUtil.hide(address, length - end, length);
        }
    }

    /**
     * 【电子邮箱】邮箱前缀仅显示第一个字母，前缀其他隐藏，用星号代替，@及后面的地址显示，比如：d**@126.com
     *
     * @param email 邮箱
     * @return 脱敏后的邮箱
     */
    public static String email(String email) {
        if (StrUtil.isBlank(email)) {
            return "";
        } else {
            int index = StrUtil.indexOf(email, '@');
            return index <= 1 ? email : StrUtil.hide(email, 1, index);
        }
    }

    /**
     * 【密码】密码的全部字符都用*代替，比如：******
     *
     * @param password 密码
     * @return 脱敏后的密码
     */
    public static String password(String password) {
        return StrUtil.isBlank(password) ? "" : StrUtil.repeat('*', password.length());
    }

    /**
     * 【中国车牌】车牌中间用*代替 eg1：null -》 "" eg1："" -》 "" eg3：苏D40000 -》 苏D4***0 eg4：陕A12345D -》 陕A1****D eg5：京A123 -》 京A123 如果是错误的车牌，不处理
     *
     * @param carLicense 完整的车牌号
     * @return 脱敏后的车牌号
     */
    public static String carLicense(String carLicense) {
        if (StrUtil.isBlank(carLicense)) {
            return "";
        } else {
            if (carLicense.length() == 7) {
                carLicense = StrUtil.hide(carLicense, 3, 6);
            } else if (carLicense.length() == 8) {
                carLicense = StrUtil.hide(carLicense, 3, 7);
            }

            return carLicense;
        }
    }

    /**
     * 银行卡号脱敏 eg: 1101 **** **** **** 3256
     *
     * @param bankCardNo 银行卡号
     * @return 脱敏后的银行卡号
     */
    public static String bankCard(String bankCardNo) {
        if (StrUtil.isBlank(bankCardNo)) {
            return bankCardNo;
        } else {
            bankCardNo = StrUtil.trim(bankCardNo);
            if (bankCardNo.length() < 9) {
                return bankCardNo;
            } else {
                int length = bankCardNo.length();
                int midLength = length - 8;
                StringBuilder buf = new StringBuilder();
                buf.append(bankCardNo, 0, 4);

                for (int i = 0; i < midLength; ++i) {
                    if (i % 4 == 0) {
                        buf.append(' ');
                    }

                    buf.append('*');
                }

                buf.append(' ').append(bankCardNo, length - 4, length);
                return buf.toString();
            }
        }
    }
}
